using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace TestMonkey.Core
{
    public abstract class ConstructorTemplateProcessor : TemplateProcessor
    {

        public virtual string PartialTemplateFileName(Type type, ConstructorInfo constructor)
        {
            return GetType().Name + "_Partial";
        }

        public override bool ShouldRun(Type type)
        {
            foreach (var constructor in type.GetConstructors())
            {
                if (ShouldRun(type, constructor))
                    return true;
            }
            return false;
        }

        public virtual bool ShouldRun(Type type, ConstructorInfo constructor)
        {
            return true;
        }

        public string ProcessPartialTemplate(Type type, ConstructorInfo constructor, int constructorIndex)
        {
            var template = LoadTemplate(PartialTemplateFileName(type, constructor), false);

            OnProcessPartialTemplate(type, constructor, constructorIndex, template);

            return template.ToString();
        }

        protected virtual void OnProcessPartialTemplate(Type type, ConstructorInfo constructor, int constructorIndex, StringBuilder template)
        {
            template.Replace("$TestNamespace$", Setup.TestNamespace);
            template.Replace("$TestClassName$", Setup.GetTestClassName(type));
            template.Replace("$ClassName$", type.Name);
            template.Replace("$ClassNamespace$", type.Namespace);

            template.Replace("$TestName$", GetType().Name);
            template.Replace("$Constructor-Index$", constructorIndex.ToString());

            var tags = new List<string>();
            if (Setup.UseTags)
            {
                tags.Add(String.Format("[Microsoft.Silverlight.Testing.Tag(\"{0}\")]", GetType().Name));
            }
            template.Replace("$Tags$", string.Join(Environment.NewLine + "\t\t", tags));
        }

        protected override void OnProcessTemplate(Type type, StringBuilder template)
        {
            base.OnProcessTemplate(type, template);

            var parts = new List<string>();
            ConstructorInfo[] typeGetConstructors = type.GetConstructors();
            for (var i = 0; i < typeGetConstructors.Length; i++)
            {
                var constructor = typeGetConstructors[i];
                if (ShouldRun(type, constructor))
                    parts.Add(ProcessPartialTemplate(type, constructor, i));
            }

            template.Replace("$Parts$", string.Join(Environment.NewLine, parts));

        }

    }
}
